#pragma once
#include "..\nodes\SpriteNode.h"
#include "..\base\Controller.h"
#include "..\nodes\PlainTextNode.h"
#include "..\nodes\GroupNode.h"
#include "..\utils\StringUtils.h"

namespace ds {

struct MenuEvent {
	//std::string name;
	int id;
	int type;
};

class MenuComponent : public GroupNode , public MouseController{

struct MenuLink {
	Vec2 pos;
	Vec2 extent;
	std::string text;
	int id;
	bool active;
};

typedef std::vector<MenuLink> MenuLinks;
typedef std::map<std::string,ds::PlainTextNode*> TextNodeMap;

public:
	MenuComponent(const std::string& name,const std::string& materialName,const std::string& layerName);
	virtual ~MenuComponent() {}
	
	void addLink(int id,const std::string& textNodeName,int x,int y,int width,int height,const std::string& txt,const Color& color = Color(1.0f,1.0f,1.0f,1.0f));
	void setLinkColor(int id,const std::string& textNodeName,const Color& color);
	void setLinkColor(int id,const Color& color);
	void setLinkState(int id,const std::string& textNodeName,bool state);
	
	void update(float elapsedTime);
	void OnButtonDown( int button ) {
		m_Pressed = true;
	}
	void OnButtonUp( int button );
	void setMouseOffset(int x,int y) {
		m_Offset = Vec2(x,y);
	}
	virtual bool onActivation() {
		m_Sprites->setActive(true);
		TextNodeMap::iterator it = m_TextNodeMap.begin();
		while ( it != m_TextNodeMap.end() ) {
			it->second->setActive(true);
			++ it;
		}
		return true;
	}
	virtual bool onDeactivation() {
		m_Sprites->setActive(false);
		TextNodeMap::iterator it = m_TextNodeMap.begin();
		while ( it != m_TextNodeMap.end() ) {
			it->second->setActive(false);
			++ it;
		}		
		return true;
	}
	void setActive(bool act) {
		LOG(logINFO) << "menu " << m_Name << " setting active " << act;
		m_SelectedID = -1;
		if ( act ) {
			onActivation();
		}
		else {
			onDeactivation();
		}
		Node::setActive(act);
	}	
	void addSprite(const Vec2& pos,const Rect& rect) {
		m_Sprites->add(pos,rect);
	}	
	void createTextNode(const std::string& name,const std::string& fontResource) {
		PlainTextNode* textNode = new PlainTextNode(name,fontResource);
		//WorldLayer wl = gEngine->getWorld().getLayerByName(m_LayerName.c_str());
		//gEngine->getWorld().attachNode(textNode,wl);
		addNode(textNode);
		m_TextNodeMap[name] = textNode;
	}
	int addText(const std::string& textNodeName,int x,int y,const std::string& txt,int specialIndex = -1) {
		return addText(textNodeName,Vec2(x,y),txt,specialIndex);		
	}
	void setText(const std::string& textNodeName,int index,int x,int y,const std::string& txt) {
		PlainTextNode* tn = m_TextNodeMap[textNodeName];
		if ( tn != 0 ) {
			tn->setText("Text"+string::to_string(index),Vec2(x,y),Color(1.0f,1.0f,1.0f,1.0f),"%s",txt.c_str());
		}
	}	
	int addText(const std::string& textNodeName,Vec2& pos,const std::string& txt,int specialIndex = -1) {
		int ret = -1;
		PlainTextNode* tn = m_TextNodeMap[textNodeName];
		if ( tn != 0 ) {
			int cnt = specialIndex;
			if ( cnt == -1 ) {
				++m_TextCounter;
				cnt = m_TextCounter;
			}
			tn->setText("Text"+string::to_string(cnt),pos,Color(1.0f,1.0f,1.0f,1.0f),"%s",txt.c_str());
			ret = cnt;
		}
		return ret;
	}
	void setLinkColor(const ds::Color& color) {
		m_LinkColor = color;
	}
	void setHoverColor(const ds::Color& color) {
		m_HoverColor = color;
	}
private:
	bool isInside(const Vec2& mousePos,MenuLink* menuLink) const;
	//
	ds::Color m_LinkColor;
	ds::Color m_HoverColor;
	std::string m_Name;
	MenuLinks m_Links;
	int m_SelectedID;
	Vec2 m_Offset;
	bool m_Pressed;
	std::string m_LayerName;
	int m_TextCounter;
	SpriteNode* m_Sprites;
	std::string m_Material;
	std::string m_NextStateName;
	TextNodeMap m_TextNodeMap;

};

}


